﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Net;
using System.Security.Cryptography.X509Certificates;
using System.Net.Security;
using System.Text;
using System.IO;
using Newtonsoft.Json;
using RoomSvc.Data;

namespace RoomService.Service
{
    public class ServiceClient
    {
        #region Static Members

        private static string _serviceAddress = "http://23.23.80.142/RoomServiceWCF/";

        #endregion

        #region Client Communication

        /// <summary>
        /// Retrieves data from the service
        /// </summary>
        /// <param name="uri">The url of the service endpoint</param>
        /// <returns>The response from the service as a JSON string</returns>
        private static string _callGetService(string uri)
        {
            string url = _serviceAddress + uri;
            // declare httpwebrequest with url defined above
            HttpWebRequest webrequest = (HttpWebRequest)WebRequest.Create(url);
            webrequest.Method = "GET";
            webrequest.Credentials = new NetworkCredential("Administrator", "$bRC;DZQN2?");
            webrequest.ContentType = "application/x-www-form-urlencoded";
            /* set up certificate trust
            ServicePointManager.ServerCertificateValidationCallback =
            new RemoteCertificateValidationCallback(
            delegate(object sender2, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
            {
                return true;
            });*/
            // declare & read response from service
            HttpWebResponse webresponse;
            Encoding enc;
            StreamReader responseStream;
            string strResult = string.Empty;
            try
            {
                webresponse = (HttpWebResponse)webrequest.GetResponse();
                enc = System.Text.Encoding.GetEncoding("utf-8");
                responseStream = new StreamReader(webresponse.GetResponseStream(), enc);
                strResult = responseStream.ReadToEnd();
                responseStream.Close();
                webresponse.Close();
            }
            catch (WebException we)
            {
                strResult = "A Web Exception has occurred\n\n" + we.Message;
            }

            return strResult;
        }

        /// <summary>
        /// Sends data to the service via the HTTP POST.
        /// </summary>
        /// <param name="uri">The uri template for the desired method.</param>
        /// <param name="json">The JSON object to send.</param>
        /// <returns></returns>
        private static string _callPostService(string uri, string json)
        {
            string url = _serviceAddress + uri;
            byte[] buffer = Encoding.UTF8.GetBytes(json);
            HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
            request.Method = "POST";
            request.KeepAlive = true;
            request.Credentials = new NetworkCredential("Administrator", "$bRC;DZQN2?"); //our new password is $bRC;DZQN2? and the username is student042
            request.ContentType = "application/x-www-form-urlencoded";
            // set up certificate trust
            ServicePointManager.ServerCertificateValidationCallback +=
                delegate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
                {
                    return true;
                };
            StreamWriter sw = new StreamWriter(request.GetRequestStream());
            sw.Write(json);
            sw.Close();
            HttpWebResponse webresponse;
            Encoding enc;
            StreamReader responseStream;
            string strResult = string.Empty;
            try
            {
                webresponse = (HttpWebResponse)request.GetResponse();
                enc = System.Text.Encoding.GetEncoding("utf-8");
                responseStream = new StreamReader(webresponse.GetResponseStream(), enc);
                strResult = responseStream.ReadToEnd();
                responseStream.Close();
                webresponse.Close();

            }
            catch (WebException we)
            {
                strResult = "Rodger:A Web Exception has occurred\n\n" + we.Message;
            }

            return strResult;
        }

        #endregion

        //Untested
        #region Service Methods

        #region GET

        public static AddressType[] GetAddressTypes()
        {
            AddressType[] atyp = (AddressType[])JsonConvert.DeserializeObject(_callGetService("address/type"), typeof(AddressType[]));
            return atyp;
        }

        public static AddressType GetAddressType(string atypid)
        {
            AddressType atyp = (AddressType)JsonConvert.DeserializeObject(_callGetService("address/type/" + atypid), typeof(AddressType));
            return atyp;
        }

        public static PersonType[] GetPersTypes()
        {
            PersonType[] ptyps = (PersonType[])JsonConvert.DeserializeObject(_callGetService("person/type"), typeof(PersonType[]));
            return ptyps;
        }

        public static PersonType GetPersType(string ptypid)
        {
            PersonType ptyp = (PersonType)JsonConvert.DeserializeObject(_callGetService("person/type/" + ptypid), typeof(PersonType));
            return ptyp;
        }

        public static ListingType[] GetListingTypes()
        {
            ListingType[] ltyps = (ListingType[])JsonConvert.DeserializeObject(_callGetService("listing/type"), typeof(ListingType[]));
            return ltyps;
        }

        public static ListingType GetListingType(string ltypid)
        {
            ListingType ltyp = (ListingType)JsonConvert.DeserializeObject(_callGetService("listing/type/" + ltypid), typeof(ListingType));
            return ltyp;
        }

        public static Listing[] GetListings()
        {
            Listing[] ls = (Listing[])JsonConvert.DeserializeObject(_callGetService("listing"), typeof(Listing[]));
            return ls;
        }

        public static Listing GetListing(string listid)
        {
            Listing l = (Listing)JsonConvert.DeserializeObject(_callGetService("listing/" + listid), typeof(Listing));
            return l;
        }

        public static Address[] GetAddresses()
        {
            Address[] addrs = (Address[])JsonConvert.DeserializeObject(_callGetService("address"), typeof(Address[]));
            return addrs;
        }
        
        public static Address GetAddress(string addrid)
        {
            Address addr = (Address)JsonConvert.DeserializeObject(_callGetService("address/" + addrid), typeof(Address));
            return addr;
        }

        public static Utility[] GetUtilies()
        {
            Utility[] utils = (Utility[])JsonConvert.DeserializeObject(_callGetService("utility"), typeof(Utility[]));
            return utils;
        }

        public static Utility GetUtility(string utilid)
        {
            Utility util = (Utility)JsonConvert.DeserializeObject(_callGetService("utilities/" + utilid), typeof(Utility));
            return util;
        }

        public static Person[] GetPersons()
        {
            Person[] perss = (Person[])JsonConvert.DeserializeObject(_callGetService("person"), typeof(Person[]));
            return perss;
        }

        public static Person GetPerson(string persid)
        {
            Person pers = (Person)JsonConvert.DeserializeObject(_callGetService("person/" + persid), typeof(Person));
            return pers;
        }

        #endregion

        #region POST

        public static PostResponse PostListing(Listing listIn)
        {
            PostResponse pr = (PostResponse)JsonConvert.DeserializeObject(_callPostService("listing/new", JsonConvert.SerializeObject(listIn)), typeof(PostResponse));
            return pr;
        }

        public static PostResponse PostPerson(Person persIn)
        {
            PostResponse pr = (PostResponse)JsonConvert.DeserializeObject(_callPostService("person/new", JsonConvert.SerializeObject(persIn)), typeof(PostResponse));
            return pr;
        }

        #endregion

        #endregion
    }
}